using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data;
using EAT.Common;
using System.Configuration;
using System.DirectoryServices;
using System.Web.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using System.ComponentModel;
using System.Text;


namespace ECTSUserMgmtExtension
{
    public class ProvisioningApprovalExtension : System.Web.UI.WebControls.WebParts.WebPart
    {
        #region AdditionalEmails
        private string m_additionalEmails;
        [WebBrowsable]
        [WebDisplayName("Additional E-Mails")]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Configuration")]
        [DefaultValue("")]
        public string AdditionalEmails
        {
            get { return m_additionalEmails; }
            set { m_additionalEmails = value; }
        }
        #endregion

        #region SupportEmail
        private string m_supportEmail;
        [WebBrowsable]
        [WebDisplayName("Support E-Mail")]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Configuration")]
        [DefaultValue("")]
        public string SupportEmail
        {
            get { return m_supportEmail; }
            set { m_supportEmail = value; }
        }
        #endregion

        #region Salutation
        private string m_salutation;
        [WebBrowsable]
        [WebDisplayName("E-Mail Salutation")]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Configuration")]
        [DefaultValue("")]
        public string Salutation
        {
            get { return m_salutation; }
            set { m_salutation = value; }
        }
        #endregion

        #region ApprovedUserSPGroup
        private string m_approvedUserSPGroup;
        [WebBrowsable]
        [WebDisplayName("Add to Default SharePoint Group")]
        [WebPartStorage(Storage.Shared)]
        [Personalizable(PersonalizationScope.Shared)]
        [Category("Configuration")]
        [DefaultValue("")]
        public string ApprovedUserSPGroup
        {
            get { return m_approvedUserSPGroup; }
            set { m_approvedUserSPGroup = value; }
        }
        #endregion

        #region UserManager
        private cUserManager _cUserManager;
        protected cUserManager UserManager
        {
            get
            {
                if (_cUserManager == null)
                    _cUserManager = new cUserManager(ConfigurationManager.ConnectionStrings["ADAMConnectionString"].ConnectionString);

                return _cUserManager;
            }
        }
        #endregion

        #region UserTable
        private DataTable UserTable
        {
            get
            {
                DataTable userTable = new UserDataTable(UserManager, "(|(msDS-UserAccountDisabled=TRUE)(msDS-UserAccountDisabled=1))");
                return userTable;
            }
        }
        #endregion

        private DataGrid m_displayGrid;
        protected override void CreateChildControls()
        {
            m_displayGrid = new DataGrid();
            m_displayGrid.AutoGenerateColumns = false;
            m_displayGrid.Width = new Unit("100%");
            m_displayGrid.AlternatingItemStyle.CssClass = "ms-alternating";

            ButtonColumn userApproval = new ButtonColumn();
            userApproval.ButtonType = ButtonColumnType.LinkButton;
            userApproval.Text = "Approve";
            userApproval.CommandName = "Approve";
            userApproval.HeaderStyle.CssClass = "leftNav1";
            userApproval.HeaderStyle.Width = new Unit("20%");

            ButtonColumn userDeny = new ButtonColumn();
            userDeny.ButtonType = ButtonColumnType.LinkButton;
            userDeny.Text = "Deny";
            userDeny.CommandName = "Deny";
            userDeny.HeaderStyle.CssClass = "leftNav1";
            userDeny.HeaderStyle.Width = new Unit("20%");

            BoundColumn userNameColumn = CreateColumn(UserDataTable.UserDataTableColumns.UserId.ToString(), "Requested Account");
            BoundColumn userFirstNameColumn = CreateColumn(UserDataTable.UserDataTableColumns.FirstName.ToString(), "First");
            BoundColumn userLastNameColumn = CreateColumn(UserDataTable.UserDataTableColumns.LastName.ToString(), "Last");
            BoundColumn userPhoneColumn = CreateColumn(UserDataTable.UserDataTableColumns.Phone.ToString(), "Phone");
            BoundColumn userServiceColumn = CreateColumn(UserDataTable.UserDataTableColumns.Service.ToString(), "Service");
            BoundColumn userJustificationColumn = CreateColumn(UserDataTable.UserDataTableColumns.Notes.ToString(), "Justification");

            m_displayGrid.Columns.Add(userApproval);
            m_displayGrid.Columns.Add(userDeny);
            m_displayGrid.Columns.Add(userNameColumn);
            m_displayGrid.Columns.Add(userFirstNameColumn);
            m_displayGrid.Columns.Add(userLastNameColumn);
            m_displayGrid.Columns.Add(userPhoneColumn);
            m_displayGrid.Columns.Add(userServiceColumn);
            m_displayGrid.Columns.Add(userJustificationColumn);

            m_displayGrid.ItemCommand += new DataGridCommandEventHandler(HandleItemCommand);

            Controls.Add(m_displayGrid);
        }

        void HandleItemCommand(object source, DataGridCommandEventArgs e)
        {
            string userName = e.Item.Cells[2].Text;
            switch (((LinkButton)e.CommandSource).CommandName)
            {
                case "Approve":
                    SPSecurity.RunWithElevatedPrivileges(
                        delegate()
                        {
                            DirectoryEntry user = UserManager.FindUser(userName);
                            user.Options.PasswordPort = UserManager.Connection.Port();
                            string password = Membership.GeneratePassword(9, 2);
                            user.Invoke("SetPassword", new object[] { password });
                            user.Properties["msDS-UserAccountDisabled"].Value = false;
                            user.CommitChanges();

                            UserManager.SetPwdGenerated(userName);

                            if (!string.IsNullOrEmpty(ApprovedUserSPGroup))
                            {
                                try
                                {
                                    SPGroup group = SPContext.Current.Web.Groups[ApprovedUserSPGroup];
                                    
                                    string un;
                                    try { un = Membership.Provider.Name + ":" + Membership.GetUser(userName).UserName; }
                                    catch { un = userName; }

                                    string displayName;
                                    try { displayName = user.Properties["displayName"].Value.ToString(); }
                                    catch { displayName = userName; }

                                    group.AddUser(un, userName, displayName, "");
                                    Controls.Add(new LiteralControl("<p>Account " + userName + " has been added to the <i>" + ApprovedUserSPGroup + "</i> SharePoint Group.</p>"));
                                }
                                catch (Exception ex)
                                {
                                    Controls.Add(new LiteralControl("<p>Error while adding account " + userName + " to SharePoint Group <i>" + ApprovedUserSPGroup + "</i><br/>"));
                                    Controls.Add(new LiteralControl("Message: " + ex.Message + "<br/>" + SPHttpUtility.HtmlEncode(ex.StackTrace) + "</p>"));
                                }
                            }

                            StringBuilder builder = new StringBuilder("<p>Your request for an account has been approved.  To access the site use the following account information.<br/>");
                            builder.AppendFormat("User Name: {0}<br/>", userName);
                            builder.AppendFormat("Password: {0}<br/>", password);
                            if (!string.IsNullOrEmpty(SupportEmail))
                                builder.AppendFormat("If you have any issues please contact support at {0}", SupportEmail);
                            builder.AppendFormat("</p><p>Thank You,<br/>{0}</p>", Salutation);

                            if (!SPUtility.SendEmail(SPContext.Current.Web, false, false, userName + AdditionalEmails, "Approved Account", builder.ToString()))
                            {
                                Controls.Add(new LiteralControl("<p>Failed to send password.  The user's password was set to <b>" + password + "</b> please manually send this information to the user.</p>"));
                            }

                            Controls.Add(new LiteralControl("<p>Account " + userName + " approved.</p>"));
                        }
                    );
                    break;

                case "Deny":
                    SPSecurity.RunWithElevatedPrivileges(
                        delegate()
                        {
                            UserManager.DeleteUser(userName);
                            Controls.Add(new LiteralControl("<p>Account " + userName + " has been removed from ADAM.</p>"));

                            SPUtility.SendEmail(SPContext.Current.Web, false, false, userName, "Denied Account",
                                "<p>Your request for an account has been denied.  If you belive this is an error please contact the support team at the email below.</p>"
                                + string.Format("<p>Thank You,<br/>{0}<br/>{1}</p>", Salutation, SupportEmail));
                        }
                    );
                    break;
                default:
                    break;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            m_displayGrid.DataSource = UserTable;
            m_displayGrid.DataBind();

            base.OnPreRender(e);
        }

        private BoundColumn CreateColumn(string dataField, string columnHeaderText)
        {
            BoundColumn column = new BoundColumn();
            column.DataField = dataField;
            column.Visible = true;
            column.HeaderText = columnHeaderText;
            column.HeaderStyle.CssClass = "leftNav1";

            return column;
        }
    }
}
